package com.hd.trans.network;

import android.text.TextUtils;
import android.util.Log;

import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonWriter;
import com.hd.trans.network.bean.aiChat.AiChatError;
import com.hd.trans.network.bean.aiChat.AiChatResponse;
import com.hd.trans.network.bean.aiChat.AiChatSseFrg;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.nio.charset.Charset;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import okhttp3.MediaType;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import okio.Buffer;
import retrofit2.Converter;
import retrofit2.Retrofit;

/**
 * @Author : HeYan
 * @Time : 2023/5/8 11:55
 * @Description : chatGPT 问答  Sse 接口解析
 */
public class GPTConverterFactory extends Converter.Factory {
    /**
     * Create an instance using a default {@link Gson} instance for conversion. Encoding to JSON and
     * decoding from JSON (when no charset is specified by a header) will use UTF-8.
     */
    public static GPTConverterFactory create() {
        return create(new Gson());
    }

    /**
     * Create an instance using {@code gson} for conversion. Encoding to JSON and decoding from JSON
     * (when no charset is specified by a header) will use UTF-8.
     */
    @SuppressWarnings("ConstantConditions") // Guarding public API nullability.
    public static GPTConverterFactory create(Gson gson) {
        if (gson == null) throw new NullPointerException("gson == null");
        return new GPTConverterFactory(gson);
    }

    private final Gson gson;

    private GPTConverterFactory(Gson gson) {
        this.gson = gson;
    }

    @Override
    public Converter<ResponseBody, ?> responseBodyConverter(
            Type type, Annotation[] annotations, Retrofit retrofit) {
//        TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
        return StringResponseBodyConverter.INSTANCE;
    }

    @Override
    public Converter<?, RequestBody> requestBodyConverter(
            Type type,
            Annotation[] parameterAnnotations,
            Annotation[] methodAnnotations,
            Retrofit retrofit) {
        TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
        return new GsonRequestBodyConverter<>(gson, adapter);
    }

    static class GsonRequestBodyConverter<T> implements Converter<T, RequestBody> {
        private static final MediaType MEDIA_TYPE = MediaType.get("application/json; charset=UTF-8");
        private static final Charset UTF_8 = Charset.forName("UTF-8");

        private final Gson gson;
        private final TypeAdapter<T> adapter;

        GsonRequestBodyConverter(Gson gson, TypeAdapter<T> adapter) {
            this.gson = gson;
            this.adapter = adapter;
        }

        @Override
        public RequestBody convert(T value) throws IOException {
            Buffer buffer = new Buffer();
            Writer writer = new OutputStreamWriter(buffer.outputStream(), UTF_8);
            JsonWriter jsonWriter = gson.newJsonWriter(writer);
            adapter.write(jsonWriter, value);
            jsonWriter.close();
            return RequestBody.create(MEDIA_TYPE, buffer.readByteString());
        }
    }

    static final class StringResponseBodyConverter implements Converter<ResponseBody, AiChatResponse> {
        static final StringResponseBodyConverter INSTANCE = new StringResponseBodyConverter();

        private final Gson gson = new Gson();

        @Override
        public AiChatResponse convert(ResponseBody value) throws IOException {
            String response = value.string();
            Log.e("AiTransResponse", "type = "+ Objects.requireNonNull(value.contentType()).type());
            Log.e("AiTransResponse", response);
            //
            if (Objects.requireNonNull(value.contentType()).type().contains("application")) {
                AiChatError error = gson.fromJson(response, AiChatError.class);
                if(error != null){
                    AiChatResponse aiTransResponse;
                    //data: {"code":101227:"message":"呀！忙不过来啦~请稍后再试~"}
                    //data: {"code":101221:"message":"文本合法性验证不通过"}
                    //data: {"code":101005,"message":"公共参数缺失"}
                    if(error.getCode() == 100422){
                        aiTransResponse = new AiChatResponse(error.getCode(), "账号未登录，无法与我建立对话哦。", response, "DONE");
                    }else {
                        aiTransResponse = new AiChatResponse(error.getCode(), error.getMessage(), response, "DONE");
                    }
                    return aiTransResponse;
                }
                return gson.fromJson(response, AiChatResponse.class);
            } else if (Objects.requireNonNull(value.contentType()).type().contains("text")) {
                /**
                 * response = ?
                 *     1.
                 *     id: e8950c07-22a2-471e-b11d-b5569d31832d
                 *     event: message
                 *     data: {"output":"再见","index":0,"stop":1}
                 *
                 *     2.
                 *     data: {"code":1502,"message":"当前用户请求过多，请您稍后再试"}
                 */

                //直接获取output内容json
                String regex = "\\{\"output\":([\\s\\S]*?)\\\"stop\":([\\s\\S]*?)\\}";
                Pattern pattern = Pattern.compile(regex);
                Matcher matcher = pattern.matcher(response);
                StringBuilder stringBuilder = new StringBuilder();
                int i = 0;
                while (matcher.find(i)) {
                    i = matcher.start() + 1;
                    //Log.e("convert", matcher.group());
                    AiChatSseFrg bean = gson.fromJson(matcher.group(), AiChatSseFrg.class);
                    stringBuilder.append(bean.getOutput());
                }
                if (TextUtils.isEmpty(stringBuilder.toString().trim())) {
                    //获取error内容json
                    String regexError = "\\{\"code\":([\\s\\S]*?)\\\"message\":([\\s\\S]*?)\\}";
                    Pattern patternError = Pattern.compile(regexError);
                    Matcher matcherError = patternError.matcher(response);
                    if(matcherError.find(0)){
                        AiChatError error = gson.fromJson(matcherError.group(), AiChatError.class);
                        return new AiChatResponse(error.getCode(), error.getMessage(), response, "DONE");
                    }
                    return new AiChatResponse(-1, "抱歉，识别失败！code=-1", response, "DONE");
                } else {
                    return new AiChatResponse(10000, stringBuilder.toString(), "", "DONE");
                }
            } else {
                return new AiChatResponse(-2, "抱歉，识别失败！code=-2", response, "DONE");
            }
        }
    }
}
